home *** CD-ROM | disk | FTP | other *** search
- /*
- * Subject: Re: Wanted: traceback subroutine
- * Newsgroups: comp.sys.sgi
- * Summary: Another code example of traceback
- *
- * This very simplified traceback code relies on /usr/lib/libexc.a.
- * Compile and run the sample with:
- * (Sample run)
- * #cc myfile.c traceback.c -lexc ; ./a.out
- * here
- * 0040023c printStackTraceback
- * 00400264 c
- * 00400284 static procedure (no name)
- * 004001ec main
- * done
- *
- * While it works for me, it is unsupported code. No warrantee!!
- *
- * The data used by this program is created by ld(1) and makes the
- * initialized-data portion of your program larger.
- *
- */
- /*
- Do not forget to add -lexc to the command line.
-
- Public Domain. Enjoy!
- Use at your own risk. No warrantee of any kind.
-
- Documentation : /usr/include/exception.h
- Original paper: A RISC Approach to Runtime Exceptions
- Mark Himelstein, Steven Correll, Kevin Enderby
- Page 239
- Proceedings, Summer USENIX 1988. San Francisco
-
- */
-
- #include <stdio.h>
- #include <exception.h>
- #include <a.out.h>
- #include <setjmp.h>
- #define MAX_PCS 1000
- static unsigned int m_stackdepth = MAX_PCS; /* how deep to log stack */
-
-
- #define LOW_TEXT 0x00010000
- #define HI_TEXT 0x10000000
- static int savepcs(char** pcs,RPDR **pdrp, int numpcs, int skip)
- {
- int slot = 0;
- jmp_buf jb;
- unsigned long pc;
- unsigned long* sp;
-
- setjmp(jb);
- pc = jb[JB_PC];
- sp = (unsigned long*) jb[JB_SP];
-
- /* walk up stack frame and save the pcs */
- while (slot < numpcs) {
- unsigned long frameoffset, framesize;
- RPDR* p = find_rpd(pc); /* /usr/lib/libexc.a call */
- if (!p) {
- /* this can't happen, right? */
- break;
- }
-
- /* lets here it for misnamed data structures */
- frameoffset = p->regoffset;
- framesize = p->frameoffset;
-
- /* back up to previous frame */
- sp = (unsigned long*) ((unsigned char*)sp + framesize);
-
- /* fetch return pc in current frame */
- pc = sp[frameoffset>>2];
- if ((pc <= LOW_TEXT) || (pc >= HI_TEXT)) {
- /* pc is garbage. stop looping */
- break;
- }
-
- /* record pc, unless we are still skipping frames */
- if (skip) {
- --skip;
- } else {
- pcs[slot] = (char*) pc;
- pdrp[slot] = p;
- ++slot;
- }
- }
- return slot;
- }
- /* number of stack frames to skip before recording */
- #define SKIP 1
-
- void printStackTraceback(FILE* fp)
- {
- char* pcs[MAX_PCS];
- RPDR* m_pdr_cache[MAX_PCS];
- int numpcs;
- int i;
-
- numpcs = savepcs(&pcs[0],m_pdr_cache, m_stackdepth, SKIP);
- for (i = 0; i < numpcs; i++) {
- RPDR *p;
- p = m_pdr_cache[i];
- (void)fprintf(fp, "%08x %s\n", pcs[i],(p && p->irpss != issNil)?
- &_procedure_string_table[p->irpss] : "(unknown)");
- }
- }
-